﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using WpfElevator.ControlPart;
using AbstractFramework.Display;
using AbstractFramework;
using AbstractFramework.LogicControl;

namespace WpfElevator.ElevatorPart
{
    //enum ElevatorState : int //state:电梯状态的枚举集合
    //{
    //    waiting = 1,//静止，等待中
    //    uping = 2,  //向上运动中
    //    downing = 3//向下运动中
    //}

    class Elevator : IElevator
    {
        //字段
        private bool needOpen = true;//用于控制电梯到达指定楼层后是否开门,默认时为开门
        private int id;  //每部电梯的id，从1开始
        private int floor;//电梯当前所在的层数
        MovementStatus state;
        private int peopleNum;//每部电梯中当前包含的人数。
        private int[] fbdFloor;
        private IController controllerOfElevator;//每个电梯的控制器
        private IElevatorDisplay elevatorDisplay; //每台电梯对应的界面显示电梯
        private IDoor door;//暂时不区分电梯门和楼层门
        private IFloorIndicatorDisplay[] upFloorIndicator;//上行楼层指示器。数组大小为楼层数。可以让每台电梯在每层共享同一个floorIndicator
        private IFloorIndicatorDisplay[] downFloorIndicator;//下行楼层指示器。
        private IInsideIndicatorDisplay insideIndicator;

        private IOutsideButtonPanelDisplay[] outsideButtonPanel;
        private IInsideButtonPanelDisplay insideButtonPanel;
        //待加 IFireButton fireButton

        private int objectPos = -1;


        //属性
        public bool NeedOpen
        {
            get { return needOpen; }
            set { needOpen = value;}
        }
        public int Id
        {
            get { return id; }
            set { id = value; }
        }
        public int Floor
        {
            get { return floor; }
            set { floor = value; }
        }
        public MovementStatus State
        {
            get
            {
                if (elevatorDisplay.getElevatorState() == ElevatorStatus.DownMoving)
                    return MovementStatus.DownMoving;
                else if (elevatorDisplay.getElevatorState() == ElevatorStatus.UpMoving)
                    return MovementStatus.UpMoving;
                else
                    return MovementStatus.Stoped;
            }
            set { state = value; }
        }
        public int PeopleNum
        {
            get { return peopleNum; }
            set { peopleNum = value; }
        }
        public int[] FbdFloor
        {
            get { return fbdFloor; }
            set { fbdFloor = value; }
        }
        public IController ControllerOfElevator
        {
            get { return controllerOfElevator; }
            set { controllerOfElevator = value; }
        }
        public IElevatorDisplay Elevator_Display
        {
            get { return elevatorDisplay; }
            set { elevatorDisplay = value; }
        }
        public IFloorIndicatorDisplay[] UpFloor_Indicator
        {
            get { return upFloorIndicator; }
            set {upFloorIndicator = value; }
        }
        public IFloorIndicatorDisplay[] DownFloor_Indicator
        {
            get { return downFloorIndicator; }
            set { downFloorIndicator = value; }
        }
        public IInsideIndicatorDisplay Inside_Indicator
        {
            get { return insideIndicator; }
            set {insideIndicator = value; }
        }
        public IOutsideButtonPanelDisplay[] OutsideButtonPanel
        {
            get { return outsideButtonPanel; }
            set { outsideButtonPanel = value; }
        }
        public IInsideButtonPanelDisplay InsideButtonPanel
        {
            get { return insideButtonPanel; }
            set { insideButtonPanel = value; }
        }
        public IDoor _Door//暂时不区分电梯门和楼层门
        {
            get { return door; }
            set { door = value; }
        }
        //方法
        public Elevator()
        {
        }
        public Elevator(int pId, int[] pFbdFloor, IController pController) //pId从1开始
        {
            this.id = pId;
            this.floor = 0;//电梯当前所在的层数
            this.state = MovementStatus.Stoped;
            this.peopleNum = 0;//每部电梯中当前包含的人数。
            this.fbdFloor = pFbdFloor;
            this.controllerOfElevator = pController;
            this.door = new Door(this);
        }

        public bool handleEmergency(int emergencyType)//处理紧急情况，如火警、超重等。处理成功，返回true
        {                                                                       //emergencyType = 0:火警; emergencyType = 1:超重
            if (emergencyType == 0) //火警,电梯就近停靠，一直处于开门状态，并不接受任何请求
            {
                if (state != MovementStatus.UpMoving && state != MovementStatus.DownMoving)//电梯保持不动
                {
                    //1.操作界面电梯开门，然后保持不动，不接受任何响应
                    //2.修改后台电梯状态
                }
            }
            return true;
        }
        public bool moveTo(int floorNum,bool openDoor)//将电梯移动到floorNum层。成功，返回true
        {
            this.needOpen = openDoor;
            this.objectPos = floorNum;

            //修改电梯当前的状态,控制电梯在界面中的移动。
            //ControlLib.Elevator 
            //ElevatorStatus { Stoped, Opened, UpMoving, DownMoving,Opening,Closing};
            ElevatorStatus elevatorNowState = elevatorDisplay.getElevatorState();
            if (elevatorNowState == ElevatorStatus.Stoped || elevatorNowState == ElevatorStatus.UpMoving || elevatorNowState == ElevatorStatus.DownMoving)
            {
                ActMove();
            }
            //else if(elevatorNowState == ElevatorStatus.UpMoving || elevatorNowState == ElevatorStatus.DownMoving)
            //{
            //    //elevatorDisplay
            //    //问题：播放动画的过程中，目标楼层的更改。
            //}
            else
                elevatorDisplay.close(true);
            return true;
        }

        private void ActMove()
        {
            if (floor > objectPos)//电梯当前所在楼层比目的楼层高，向下移动
            {
                int moveNum = floor - objectPos;
                elevatorDisplay.goDown(moveNum);
                this.Inside_Indicator.showMovementStatus(MovementStatus.DownMoving);
            }
            else if (floor < objectPos)//目的楼层比所在楼层高，向上移动
            {
                int moveNum = objectPos - floor;
                elevatorDisplay.goUp(moveNum);
                this.Inside_Indicator.showMovementStatus(MovementStatus.UpMoving);
            }
            else //floor == floorNum
            {
                if(elevatorDisplay.getElevatorState() != ElevatorStatus.Opened &&
                    elevatorDisplay.getElevatorState() != ElevatorStatus.Opening)//已经开门，或者已经正在开门，则可以不用再调用open（）
                     elevatorDisplay.open(true);
            }
        }

        public void onArrived(int objectFloor)//到达objectFloor楼层后，通知电梯
        {
            floor = objectFloor;
            //通知电梯移动完毕，等待电梯传回是否开门的操作
            if (this.needOpen == true)
                this.elevatorDisplay.open(true);//open()中电梯门打开动作执行完毕后,还要调用elevator的方法给controller发送任务执行完毕的信号。
            else //不用开门，而直接调用elevator的方法通知controller当前任务执行完毕
                onOpened();         
        }
        public void onOpened() //电梯向控制器报告当前任务执行完毕，请求撤销当前任务，同时获得下一个任务
        {           
            controllerOfElevator.nextTask(this.id);
            //objectPos = -1;
        }
        public void onClosed()
        {
            if(objectPos!=-1)
            {
                this.ActMove();
            }
        }
        public void onPositionChanged(int oldPosition, int newPosition)
        {
            this.Inside_Indicator.showText(String.Format("{0}",newPosition+1));
        }
    }
}
